<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    varying float v_PosiY;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
        v_PosiY = a_Position.y;
    }
</script>
<script id="ColorFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 u_Color;
    varying float v_PosiY;
    void main(){
        float dist = distance(gl_PointCoord, vec2(0.5,0.5));
        float a = v_PosiY * 10.0;
        if(dist < 0.5){
            gl_FragColor = vec4(1.0 - a, a, 1, 1);
        }
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly4.js'
    import Control from '../js/Control.js'

    import Geo from '../js/Poly2/Geo.js'
    import Mat from '../js/Poly2/Mat.js'
    import Obj3D from '../js/Poly2/Obj3D.js'
    import Scene from '../js/Poly2/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl", { antialias: true, });

    // gl.enable(gl.DEPTH_TEST);//开始背景遮挡会频闪
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);//去图片描边
    //#endregion



    const scene = new Scene({ gl: gl });
    scene.regProgram('color', {
        program: CreateProgram(gl,
            document.querySelector('#ColorVertexShader').innerText,
            document.querySelector('#ColorFragmentShader').innerText),
        attribs: ['a_Position'],
        uniforms: ['u_PvM4', 'u_ModelM4', 'u_PointSize', 'u_Color']
    })


    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();

    const camera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const cameraController = new CameraController({
        canvas,
        camera,
        pvMatrix: pvM4,
        eye: new Vector3(1.5, 1, 3),
        lookAt: new Vector3(0, 0, 0),
        // RotateEvent: false,
    });

    const data = {
        count: 15,
        interval: 0.2,
        pointSize: 7,

        jumpH: 0.1,
        s: 200,
    };



    //main
    const nodes = [];
    const dataYSet = [];
    let face = create(data.count, data.interval);
    createRandomY(nodes, data.count)
    scene.add(face);


    for (let i = 0; i < 10; i++) {
        console.log((Math.random() / 50).toFixed(5))
    }

    draw();


    function createRandomY(nodes, count) {
        let YSet = {
            random: 0,//生成的随机值
            set: -1,//速度,表示是在升高还是降低
        };
        const { jumpH, s } = data;
        for (let i = 0; i < nodes.length; i += 3) {
            dataYSet.push({
                random: jumpH,
                set: i % 2 == 0 ? 1 : -1,
                s: Math.random() / s,
            });
        }
    }

    function create(count, interval) {
        let arr = new Float32Array(createNodeArr(count, interval));
        let element = new Uint8Array(createElement(nodes, count));//因为Uint8Array的原因, 最大只能是16*16


        return new Obj3D({
            mat: new Mat({
                program: 'color',
                mode: ['POINTS', 'LINES'],
                data: {
                    'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                    'u_PointSize': { type: 'uniform1f', value: data.pointSize },
                    'u_Color': { type: 'uniform4fv', value: [1, 1, 1, 0.5] },
                },
            }),
            geo: new Geo({
                data: {
                    'a_Position': { size: 3, array: arr },
                },
                element: {
                    array: element,
                }
            }),
        })
    }

    function createElement(nodes, count) {
        let arr = [];
        //创建连线
        for (let i = 0; i < nodes.length / 3; i++) {
            //连横行
            // console.log(i)
            if (i % count == count - 1) {

            } else {
                arr.push(i, i + 1)
            }

            //连竖行
            if (i + count >= count ** 2) {

            } else {
                arr.push(i, i + count)
            }
        }
        return arr;
    }

    function createNodeArr(count, interval) {
        let a = count * interval / 2;
        for (let i = 0; i < count; i++) {
            let x = -a + interval * i;
            for (let j = 0; j < count; j++) {
                let y = -a + interval * j;
                nodes.push(y, Math.sin(Math.random()) / 10, x);
            }
        }
        for (let i = 0; i < nodes.length; i += 3) {
            // console.log(nodes[i], nodes[i + 1], nodes[i + 2])
        }
        return nodes;
    }



    (function ani() {

        for (let i = 0; i < dataYSet.length; i++) {
            let y = nodes[i * 3 + 1];

            const { s, random } = dataYSet[i];
            if (y > random) {
                dataYSet[i].set = -1;
            }
            if (y < 0) {
                dataYSet[i].set = 1;
            }
            nodes[i * 3 + 1] = y + (s * dataYSet[i].set);

            dataYSet[i].s = Math.random() / data.s;
        }

        face.setAttrib('a_Position', { array: new Float32Array(nodes) });

        draw();
        requestAnimationFrame(ani);
    })();

    function draw() {
        scene.draw();
    }
</script>

</html>